Re: Why are we using priveleged images / state so much? (Was Re:

Dr. Frederick B. Cohen (fc@all.net)
Thu, 6 Jul 1995 20:57:32 -0400

...
> How about an explanation here by me, that seems to explain every single
> security hole which compromised any system, that has ever existed:
>
>    "You can't get blood from a turnip."
...
>    "A computer program that lacks priveleges can't get priveleges
>     unless some process that has them, gives them to that unpriveleged
>     program.  Period.   Full stop.  There is no way for a process to give
>     away what it does not have, and there never will be.  It has to have
>     something or access to it, if it is to allow someone else to have or
>     access it.  Without priveleges, a program can do only what it is
>     permitted to do, and no more.  No matter how skilled, how capable,
>     or how talented a programmer the creator of the program is, you
>     can't get priveleges where they are nonexistent.  I would think this
>     would be self-evident, but apparently it is not."

This is certainly an important source of problems, but not the only one.
For example, denial of services and corruption is often the result of
inadequate attention to those issues rather than some problem related
to excessive privilege.

...
> It looks like people are making the same mistakes over, and over, and over
> ("Paul Robinson Presents The 'Energizer Bunny Theory of Programming
> Errors': They keep going, and going, and going...:)), and not learning
> from either history in general, or from the history of computing.  Maybe
> this stuff isn't getting published, or maybe the people doing programming
> don't do much reading of the literature, and maybe they don't do much
> reading of books on theory and prior practices, or maybe some of the
> people doing this work are not all that competent.  Or they don't care
> much since they aren't being paid to do this work:

Indeed - the problem stems, at least in part, from inadequate education of
the last generation of programmers.

> As far back as the 1960s people knew the dangers of running with
> unnecessary priveleges.  Sometime during the 1970s or 1980s, I read a
> book on operating systems design that said something like this:

In the 50s people began to consider this, in the 70s there were several
good papers on it, and by the early 1980's there had ben several books
and voluminous papers discussing this.

>      "When designing a system section to do a task that requires privelege,
>       isolate all sections that require privelege to one area of the code,
>       enable privelege only for the absolute minimum time needed to read or
>       write or update whatever it is that requires privelege to do, then
>       as soon as possible, drop priveleges and go back.  As little of the
>       system should run in priveleged mode as possible."

The so-called principle of least privilege - well known for a long time,
ignored, particularly by people who create prototype netork services
like gopher and W3 - then they fail - then after they fail, people like
us go and try to fix them - but by the time we hear about them, they are
so widespread that the fixes don't catch up to the holes for a long time.
It's a social problem.

> You look at every major security hole that gave people ROOT priveleges or
> other such things.  If there wasn't a way to get priveleges in the first
> place, people couldn't have done things that way.  Let me make some
> suggestions on how to fix the problem.
>
>   1.  Don't have anything that is priveleged at all that runs directly from
>       a user application.  Question: can a priveleged task change the state
>       of some other task on the system, e.g. may process 14, a daemon running
>       in the background, give process 9102 priveleges?  Or must that task
>       (9102) be running a program which has setid root capability, e.g.
>       the S bit in its execute value in the directory set?  If it can give
>       priveleges to that task, let it do so for the exact minimum time
>       needed and no longer, and possibly only exactly the priveleges that
>       are needed.

This is more commonly done by passing arguments to a call from the requester
to the service running with privileges - and appropriately so.  Unfortunately,
the generation of DOS programmers don't understand this.

>   2.  Does a task need to do something directly or does it simply need
>       something done by some task on the system?   That's not an idle
>       question.  If I need to get access to a file, can I have the system
>       temporarily put me into a special group, then temporarily grant me
>       read (or read/write) access to the group that that file is assigned
>       to which happens to correspond to the group that I am temporarily
>       running under?  E.g. assign every file on the system that isn't a
>       priveleged image additionally to group "95" and the only time a
>       process is in group 95 is when it asks to be assigned to it, and
>       is there for one O/S instruction only.

This has been done in several applications - and in many cases, they
have failed because the "setuid" program was insecure.  A big problem is
that there are few well designed systems with well established criteria
for determining whether or not the privileged call is indeed secure.
Only provably correct systems have a hope of demonstrating this.

>    3. Why does the FTP daemon need to have priveleges at all?

Because the way ports are deigned under Unix, you have to be root to get
things on these privileged ports.  A much better question might be: Why
do we run these processes on privileged ports instead of unprivileged
ports? Well, if you did that, any user could set up a daemon (which they
can do anyway) and open up a big hole.  An appropriate design MIGHT have
a special user ID for each daemon and only allow that daemon on that
port with only the privileges of the special user designated for the
daemon.  This is, in effect, one of the security precautions taken by
our recently designed secure http and gopher daemons.  It is implemented
by immediate chroot and setuid to the non-privileged user as soon as the
program starts, however, if the OS supported it, even this amount of
privilege would not be needed.

>  A user dials
>       in via the FTP port (21?) on an internet connection.  The daemon sees
>       this and spawns a process to run it.  Why is it necessary that this
>       process log in at all?

It's not, however, ftp was originally designed for normal users transfering
files between their accounts.  Anonymous ftp came later and the old protocol
was grandfathered in.  Once it became widespread, it was impossible to change
the whole world.

In effect, this is what gopher and http do - they don't require authentication
and perform essentially the same function as ftp.

>  Why can't the spawned process run as user FTP
>       with, say, only the priveleges of user FTP?

They can, and in our secure http and gopher daemon, they do.  They store
log files in the chroot area with access controls so that remote users
cannot see the log files unless they are setup for world read.

Part of the problem stems from the designers of these services having a
convoluted sense of protection.  Instead of using the features of the OS
designed for protection, they go off and create novel protection schemes
without the knowledge spawned by years of experience by real experts.  The
result is this foolishness we see.

> Have the spawning process
>       (which might not need to be priveleged) log the access to the system
>       log, and the spawned process, if it has to have access to the private
>       unshared files of a specific user (non-'anonymous' FTP), issue a
>       request to have its process name changed to that user, and the
>       daemon that does that checks to see that user 'FTP' (notice I use
>       capital letters, since 'real' logins on unix systems usually use
>       lower case only, if I remember correctly), was asking for the
>       service, it would know this was the Pseudo-user FTP which was
>       asking for the request.  (Or follow the 'ps' program chain and
>       see that the 'parent' of that task/process is the FTP daemon, or
>       the Grandparent is the daemon spawner, which does run priveleged to
>       spawn tasks under different usernames, or maybe IT doesn't have to
>       either, since its username is DAESPAWN (also caps), and the same
>       thing is done for it, etc.

No reason to be that complex.  It can be done far more simply and securely.

>    4. The login programs can be set up to automatically force a username
>       to lower case when the name is accepted, and unless the job issuing
>       the spawn is priveleged, a request for the Login service or spawn
>       job under new username (if such exists), a username which is
>       capitals is forced to lower case or it is set up to do so if it is
>       requested by any task except task 1.  So only the initial task
>       which starts the system is priveleged, only it can create
>       priveleged tasks, and everything else runs nonpriveleged unless it
>       requests privelege from task 1 or the O/S and is entitled to do so.

Certain things require privilege, such as the creation of file systems,
moving information between users, system services, etc.  Unfortunately, we
rarely enforce least privileges because it's almost always easier to make
any program needing any privilege run as root.  It makes it work, even if it
introduces big holes.  It's harder to do things well than poorly.

>   5.  Force priveleged tasks to 'no error recovery'.  If any error occurs
>       at all in a priveleged task, such as asking for a file that isn't
>       there, or whatever, that error automatically forces the task to be
>       unconditionally killed.  If a program needs to check for a file, it
>       can request it from the system if it is running with the right to
>       check that file.  When it needs to open the file, it can request
>       a privelege to open that file or be handed the file handle already
>       open from a priveleged 'file opener' task.  This would make trying
>       to get a privelege by winning a race condition almost impossible,
>       would it not?

There is the more general issue of resource allocation being a problem.
One cure (that most people shun and criticize in others) is not using
allocation in your program - all static variables, etc.  It's hard to do
with some system services, but it eliminates much of the error complexity.
The secure http and gopher daemons use this to some extent and always
fail with termination and an error return.

...
>   6.  Think about how often are jobs left running with constant
>       priveleges when they need them once during the start of the job, and
>       maybe once at the end?

Almost guaranteed they do not need privilege at the end if you do it
right.  Design so that all privileged operations can happen in the first
few instructions and eliminate the overhead and complexity of having to
return to a privileged state.  It's much safer.

...
>       want to puke.  Device drivers need I/O priveleges for the devices
>       they run AND NO OTHER PRIVELEGES.  Writing to user memory can be
>       done by a special priveleged task when needed, or the memory area
>       of the user's buffer can be elided to by overlaying a new descriptor
>       giving the device driver read/write priveleges on that user's
>       memory space in that area, and only that area.

But time is often of the essence, and programmers often trade time for protection.

>   8.  I believe I am being reasonable in my expectations.  I do not think
...

I agree, but almost all programming shops and IT managers do not.  Info-sec
is a specialized field that too few know about.  We need education.

>   9.  Nobody says we have to slow down user programs, we can find ways to
>       only use priveleges when absolutely necessary.  Perhaps, during
>       initialization, all priveleged functions (opening a special private
>       file, opening a port on the network, or whatever) can be activated,
>       then the process can permanently drop all priveleges since it will
>       no longer need any priveleges (I am assuming that if you do
>       something such as open a file when priveleged, that you would not
>       normally have access to that file when not priveleged, that the
>       open and read/write capability to that file remain even if the task
>       permanently and irrevocably dismisses its priveleges.

Or you can do even better as some examples above try to point out.

> If stuff like this had been done, I think the number of accidental root
> or priveleged access holes would be reduced to maybe 1% of what they have
> been.

And then nobody would continue doing them because they cost time and money
and no known breakins would lead people to believe they didn't need security.
It's a catch 22!

> Hmm.  Why does ROOT even have to be on the system as a user account?
> There are some things people have to do as root, but why not request
> special programs (like 'Shutdown') or other features, to be set up to
> allow only users in a certain class or certain userid to do them.

This is done in some secure OSs, however, there are legitimate needs to
alter the system operation at some level, and whatever level that is,
that is where problems will start to pop up.

> For example, the only user that can do a shutdown is user SHUTDOWN, their
> login shell is a procedure that asks some questions that only admin
> people could know, and if approved, runs the program(s) to begin an
> orderly shutdown.  Emergency shutdown can be done from any admin account
> in the correct group, and/or only certain users, perhaps special
> priveleges.

That is done in most Unix systems, but root users abuse the privilege.

> There are other ideas that might be even better.  Let's just ask, does
> something need privelege to do this, can we get in, get it done, and get
> the hell out fast?  What other options do we have besides staying
> priveleged constantly?

There are also systems that implement POsets so that privilege can be
divided.  This is especially effective in networks where there is no SUP
or INF.  I published several journal articles on this in the 80s, so did
Dorathy Denning in the early 80s.  But it's not as easy to work in a
well disciplined system as in a poorly disciplined system.  You have to
think about what you are doing all the time and consider the implications.
Few programmers and sysops are able or willing to do this.

> We do not want ask "Will this code need priveleges?"  What we want to ask
> is, "Must this code have priveleges, why and when, and if so, how can we
> make that priveleged state as short a period of time as possible?"

Agreed.

> I would love to hear questions, new ideas, or comments.  Privately or to
> the list.

You got-em.

--
-> See:  Info-Sec Heaven using our New Super Secure World-Wide-Web Server
-> Free: Test your system's security (scans deeper than SATAN or ISS!)
---------------------- both at URL: http://all.net ----------------------
-> Read: "Protection and Security on the Information Superhighway"
         John Wiley and Sons, 1995 ISBN 0-471-11389-1, 320 pp, $24.95
-------------------------------------------------------------------------
   Management Analytics - 216-686-0090 - PO Box 1480, Hudson, OH 44236